/***************************************************************************\
* Copyright (C) by Keio University
* RGBDRegistration.hpp created in 10 2012.
* Mail : fdesorbi@hvrl.ics.keio.ac.jp
*
* RGBDRegistration.hpp is part of the HVRL Engine Project.
*
* The HVRL Engine Project is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The HVRL Engine Project is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
\***************************************************************************/

#ifndef _RGBD_REGISTRATION_HPP__
#define _RGBD_REGISTRATION_HPP__

#include <opencv2/opencv.hpp>
#include <string>

#include "RGBDImage.hpp"

#include "PointCloud.hpp"

namespace hvrl {

	namespace tools {

		/**
		* \brief compute the correspondences between two input images
		*
		* \param colorimageA the first input colour image
		* \param colorimageB the second input colour image
		* \param matches the result of the correspondence matching between both images
		* \param keypointsA the list of keypoints obtained in the first color image
		* \param keypointsB the list of keypoints obtained in the second color image
		* \param method defines the method used for detecting and extracting the feature points in both images. Possible methods are "FAST", "STAR", "SIFT", "SURF", "ORB", "MSER", "GFTT", "HARRIS", "Dense", "SimpleBlob"
		* \param methodmatcher defines the method used for matching features from both images. Possible methods are "BruteForce" "BruteForce-L1" "BruteForce-Hamming" "BruteForce-Hamming(2)" "FlannBased"
		* \param useCCF defines if a cross check matching needs to be applied or not
		* \return true if correspondences could be evaluated, otherwise false
		* \author Francois de Sorbier
		*/
		bool getCorrespondences(const cv::Mat3b& colorimageA,
			const cv::Mat3b& colorimageB, std::vector<cv::DMatch>& matches,
			std::vector<cv::KeyPoint>& keypointsA,
			std::vector<cv::KeyPoint>& keypointsB, const std::string& method =
			"SURF", const std::string& methodextractor = "SURF", const std::string& methodmatcher = "FlannBased",
			const bool& useCCF = true);

		/**
		* \brief compute the correspondences between one image and precomputed features
		*
		* \param colorimageA the first input colour image
		* \param descriptorsB the descriptors precomputed from a previous image
		* \param keypointsA the list of keypoints obtained in the first color image
		* \param matches the result of the correspondence matching between both images
		* \param methoddetector defines the method used for detecting the feature points in both images. Possible methods are "FAST", "STAR", "SIFT", "SURF", "ORB", "MSER", "GFTT", "HARRIS", "Dense", "SimpleBlob"
		* \param methodextractor defines the method used for extracting the feature points in both images. Possible methods are "BRIEF", "ORB", "SIFT", "SURF"
		* \param methodmatcher defines the method used for matching features from both images. Possible methods are "BruteForce" "BruteForce-L1" "BruteForce-Hamming" "BruteForce-Hamming(2)" "FlannBased"
		* \param useCCF defines if a cross check matching needs to be applied or not
		* \return true if correspondences could be evaluated, otherwise false
		* \author Francois de Sorbier
		*/
		bool getCorrespondencesWithDescriptors(const cv::Mat3b& colorimageA,
			const cv::Mat& descriptorsB, std::vector<cv::DMatch>& matches,
			std::vector<cv::KeyPoint>& keypointsA, const std::string& methoddetector = "SURF", const std::string& methodextractor = "SURF",
			const std::string& methodmatcher = "FlannBased", const bool& useCCF =
			true);

		bool computeRigidTransformationWithRANSAC(const RGBDImage* sourceColor,
			const RGBDImage* targetColor, const PointCloud *sourcepc,
			const PointCloud *targetpc, cv::Mat& R, cv::Vec3f& t,
			const std::string& methoddetector = "SURF", const std::string& methodextractor = "SURF", const std::string& methodmatcher =
			"FlannBased", const bool& useCCF = true, const unsigned int& iterations = 100);

	}

}

#endif
